package com.huawang.mdesign.model.service.inter;

import com.alibaba.druid.util.DaemonThreadFactory;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.google.common.collect.Lists;
import com.huawang.business.command.CommandAddType;
import com.huawang.business.command.CommandParameter;
import com.huawang.business.constants.CommonConstants;
import com.huawang.business.constants.ErrorCode;
import com.huawang.business.constants.ModelConstantURI;
import com.huawang.business.dto.*;
import com.huawang.business.dto.project.Project;
import com.huawang.business.entity.MofDataStore;
import com.huawang.business.exception.AbortExecutionException;
import com.huawang.business.service.judge.BusinessJudgeService;
import com.huawang.business.service.model.base.UmlService;
import com.huawang.business.service.model.core.InternalElementTree;
import com.huawang.business.service.model.core.InternalSpecificationService;
import com.huawang.business.service.model.core.InternalUmlService;
import com.huawang.business.service.model.core.ModelPropertyInfoService;
import com.huawang.business.service.model.core.project.ProjectManager;
import com.huawang.business.service.model.core.property.UpdateModelFactory;
import com.huawang.business.service.simulation.DefaultInstanceCache;
import com.huawang.business.service.simulation.SimulationInitService;
import com.huawang.business.service.transaction.TransactionServiceImpl;
import com.huawang.business.util.InstanceVoUtils;
import com.huawang.business.util.ObjectMapperFactory;
import com.huawang.business.vo.ModelResultVo;
import com.huawang.business.vo.SelectElementNode;
import com.huawang.core.definition.mof.UMLDefinitionConstants;
import com.huawang.core.definition.mof.impl.MetaEnumerationLiteral;
import com.huawang.core.definition.mof.instances.MetaClassInstance;
import com.huawang.core.semantics.entity.persistence.SimulationInstanceRecord;
import com.huawang.core.semantics.entity.queryResult.MofResultContainer;
import com.huawang.core.semantics.entity.queryResult.QueryPropertyForm;
import com.huawang.core.semantics.entity.transaction.LocalTransaction;
import com.huawang.core.semantics.exception.LocalTransactionNotStartException;
import com.huawang.core.semantics.exception.TransactionNotExistingException;
import com.huawang.mdesign.model.service.dto.CreateInstanceSpecificationDTO;
import com.huawang.mdesign.model.service.dto.InstacneSpecificationInfo;
import com.huawang.mdesign.model.service.dto.SlotInfo;
import com.huawang.mdesign.model.service.inter.DataProcessor;
import com.huawang.mdesign.model.service.inter.simulationintegration.InstanceTableSimulation;
import com.huawang.mdesign.model.service.util.LogUtil;
import com.huawang.mdesign.model.service.facade.dto.SimulationAttributeInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.huawang.business.constants.ModelActionName.UPDATE_MODEL;
import static com.huawang.mdesign.model.service.inter.DataProcessor.buildInstanceToRecord;

@Slf4j
@Service
@Primary
public class SimulationService {
    @Autowired
    private InternalUmlService internalUmlService;

    @Autowired
    private UmlService umlService;

    @Autowired
    private ProjectManager projectManager;

    @Autowired
    private ModelPropertyInfoService modelPropertyInfoService;

    @Autowired
    private InternalSpecificationService internalSpecificationService;

    @Autowired
    private InternalElementTree internalElementTree;

    @Autowired
    private TransactionServiceImpl transactionService;

    @Autowired
    private SimulationInitService simulationInitService;

    public static final String USED_IBD = "Used-IB-Diagram";
    public static final String ZERO = "0";
    public static final String SIMULATION_DATA = "SIMULATION-DATA";

    public static final String SIMULATION_ELEMENT_ATTRIBUTE = "config/SimulationElementAttributeConfig.json";

    public static final String ID = "id";

    private static final Map<String, MofDataStore> dataStore = new HashMap<>();
    private static final Map<String, Map<String, List<String>>> keyStore = new HashMap<>();

    private static final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1, new DaemonThreadFactory("AAA"));

    private static final int BATCH_SIZE = 500;

    @Nullable
    public SelectElementNode queryPackages(String projectId) {
        LogUtil.printOnlineLogs("queryPackages -> projectId: ", projectId);
        List<MetaClassInstance> packages = internalUmlService.querySpecifiedInstanceList(projectId,
                UMLDefinitionConstants.Package, false);
        return internalElementTree.parseListToTree(projectId, packages, false);
    }


    @Nullable
    public SelectElementNode queryInstancesByClassifier(String projectId, String classifierId) {
        LogUtil.printOnlineLogs("projectId: {}, classifierId: {}", projectId, classifierId);
        MetaClassInstance instance = internalUmlService.fetchExistInstance(classifierId, projectId);
        List<MetaClassInstance> classifiers = internalUmlService.findGeneralsCascade(projectId, instance.getId(), true);
        List<ModelPropertyInfo> classifierPropertyInfoList = modelPropertyInfoService.createModelPropertyInfoList(projectId,
                classifiers, Stream.of(UMLDefinitionConstants.A_classifier_instanceSpecification_instanceSpecification).collect(Collectors.toList()));
        List<MetaClassInstance> instances = classifierPropertyInfoList.stream().flatMap(classifierPropertyInfo ->
                        classifierPropertyInfo.queryListInstanceValue(UMLDefinitionConstants.A_classifier_instanceSpecification_instanceSpecification).stream())
                .collect(Collectors.toList());
        return internalElementTree.parseListToTree(projectId, instances, false);
    }

    @NotNull
    public Boolean checkElementIsSupportEmulation(String projectId, String instanceId) {
        LogUtil.printOnlineLogs("projectId: {}, instanceId: {}", projectId, instanceId);
        MetaClassInstance instance = internalUmlService.fetchInstance(instanceId, projectId);
        if (Objects.isNull(instance)) {
            return false;
        }
        Set<String> givenTypes = internalUmlService.getGivenTypes(projectId, instance);
        // 是一个实例
        if (givenTypes.contains(UMLDefinitionConstants.InstanceSpecification)) {
            List<MetaClassInstance> classifiers = internalUmlService.queryListInstanceProperty(projectId, instance,
                    UMLDefinitionConstants.InstanceSpecification_classifier);
            if (CollectionUtils.isNotEmpty(classifiers)) {
                Map<String, Set<String>> classifierGivenTypes = internalUmlService.getGivenTypes(projectId, classifiers);
                return classifiers.stream().anyMatch(classifier -> {
                    Set<String> types = classifierGivenTypes.get(classifier.getId());
                    return types.contains(UMLDefinitionConstants.SysML_Block) || types.contains(UMLDefinitionConstants.Behavior);
                });
            }
        }

        // 特殊业务不支持仿真
        if (givenTypes.contains(UMLDefinitionConstants.ReliabilityProfile_CustomizationOfFMEA_FaultTreeDiagram)
                || givenTypes.contains(UMLDefinitionConstants.Customization_FlightDiagram)) {
            return false;
        }

        List<String> canEmulations = Arrays.asList(UMLDefinitionConstants.SysML_Block, UMLDefinitionConstants.Behavior,
                UMLDefinitionConstants.UseCase, UMLDefinitionConstants.Collaboration,
                UMLDefinitionConstants.Simulation_SimulationConfig, UMLDefinitionConstants.SysMLBehaviorDiagram,
                UMLDefinitionConstants.SysMLInternalBlockDiagram, UMLDefinitionConstants.SysMLParametricDiagram);

        return CollectionUtils.containsAny(givenTypes, canEmulations);
    }

    @Nullable
    public String queryConnectUrl(String projectId) {
        LogUtil.printOnlineLogs("queryConnectUrl -> projectId: ", projectId);
        Project project = projectManager.getProject(projectId);
        if (project == null) {
            return null;
        }

        projectManager.flushDb(projectId);
        return project.getDbUrl();
    }

    @Nullable
    public String querySimulationJsonDataCount(String projectId, List<String> instanceIds, String start, String oldUuid) {
        LogUtil.printOnlineLogs("projectId: {}, instanceIds: {}, start: {}, oldUuid: {}", projectId, instanceIds, start, oldUuid);
        String dataCount = null;
        if (ZERO.equals(start)) {
            long startTime = System.currentTimeMillis();
            final MofDataStore mofDataStore = querySimulationJsonDataInfo(projectId, instanceIds);
            log.info("仿真数据获取消耗时间:" + (System.currentTimeMillis() - startTime));
            if (Objects.isNull(mofDataStore)) {
                return null;
            }
            Collections.sort(instanceIds);
            final String uuid = SIMULATION_DATA + UUID.randomUUID();

            final Map<String, String> data = new HashMap<>();
            int instanceMapCount = mofDataStore.getInstanceMap().size();
            int booleanPropertyMapCount = mofDataStore.getBooleanPropertyMap().size();
            int integerPropertyMapCount = mofDataStore.getIntegerPropertyMap().size();
            int doublePropertyMapCount = mofDataStore.getDoublePropertyMap().size();
            int stringPropertyMapCount = mofDataStore.getStringPropertyMap().size();
            int instancePropertyCount = mofDataStore.getInstancePropertyMap().size();
            int listStringPropertyCount = mofDataStore.getListStringPropertyMap().size();
            int listInstancePropertyCount = mofDataStore.getListInstancePropertyMap().size();
            int instanceTypeCount = mofDataStore.getInstanceTypeMap().size();
            int enumLiteralCount = mofDataStore.getEnumLiteralMap().size();
            int listBooleanPropertyCount = mofDataStore.getListBooleanPropertyMap().size();
            int listIntegerPropertyCount = mofDataStore.getListIntegerPropertyMap().size();
            int listDoublePropertyCount = mofDataStore.getListDoublePropertyMap().size();
            data.put(CommonConstants.SIMULATION_INSTANCE, String.valueOf(instanceMapCount));
            data.put(CommonConstants.SIMULATION_BOOLEAN_PROPERTY, String.valueOf(booleanPropertyMapCount));
            data.put(CommonConstants.SIMULATION_INTEGER_PROPERTY, String.valueOf(integerPropertyMapCount));
            data.put(CommonConstants.SIMULATION_DOUBLE_PROPERTY, String.valueOf(doublePropertyMapCount));
            data.put(CommonConstants.SIMULATION_STRING_PROPERTY, String.valueOf(stringPropertyMapCount));
            data.put(CommonConstants.SIMULATION_INSTANCE_PROPERTY, String.valueOf(instancePropertyCount));
            data.put(CommonConstants.SIMULATION_LIST_STRING_PROPERTY, String.valueOf(listStringPropertyCount));
            data.put(CommonConstants.SIMULATION_LIST_INSTANCE_PROPERTY, String.valueOf(listInstancePropertyCount));
            data.put(CommonConstants.SIMULATION_ENUM_LITERAL, String.valueOf(enumLiteralCount));
            data.put(CommonConstants.SIMULATION_LIST_BOOLEAN_PROPERTY, String.valueOf(listBooleanPropertyCount));
            data.put(CommonConstants.SIMULATION_INSTANCE_TYPE, String.valueOf(instanceTypeCount));
            data.put(CommonConstants.SIMULATION_LIST_DOUBLE_PROPERTY, String.valueOf(listDoublePropertyCount));
            data.put(CommonConstants.SIMULATION_LIST_INTEGER_PROPERTY, String.valueOf(listIntegerPropertyCount));
            List<String> instanceMapKeys = new ArrayList<>(mofDataStore.getInstanceMap().keySet());
            List<String> booleanPropertyMapKeys = new ArrayList<>(mofDataStore.getBooleanPropertyMap().keySet());
            List<String> integerPropertyMapKeys = new ArrayList<>(mofDataStore.getIntegerPropertyMap().keySet());
            List<String> doublePropertyMapKeys = new ArrayList<>(mofDataStore.getDoublePropertyMap().keySet());
            List<String> stringPropertyMapKeys = new ArrayList<>(mofDataStore.getStringPropertyMap().keySet());
            List<String> instancePropertyMapKeys = new ArrayList<>(mofDataStore.getInstancePropertyMap().keySet());
            List<String> listStringPropertyMapKeys = new ArrayList<>(mofDataStore.getListStringPropertyMap().keySet());
            List<String> listInstancePropertyMapKeys = new ArrayList<>(mofDataStore.getListInstancePropertyMap().keySet());
            List<String> instanceTypeMapKeys = new ArrayList<>(mofDataStore.getInstanceTypeMap().keySet());
            List<String> enumLiteralMapKeys = new ArrayList<>(mofDataStore.getEnumLiteralMap().keySet());
            List<String> listBooleanPropertyMapKeys = new ArrayList<>(mofDataStore.getListBooleanPropertyMap().keySet());
            List<String> listIntegerPropertyMapKeys = new ArrayList<>(mofDataStore.getListIntegerPropertyMap().keySet());
            List<String> listDoublePropertyMapKeys = new ArrayList<>(mofDataStore.getListDoublePropertyMap().keySet());
            long start1 = System.currentTimeMillis();
            Collections.sort(instanceMapKeys);
            Collections.sort(booleanPropertyMapKeys);
            Collections.sort(integerPropertyMapKeys);
            Collections.sort(doublePropertyMapKeys);
            Collections.sort(stringPropertyMapKeys);
            Collections.sort(instancePropertyMapKeys);
            Collections.sort(listStringPropertyMapKeys);
            Collections.sort(listInstancePropertyMapKeys);
            Collections.sort(instanceTypeMapKeys);
            Collections.sort(enumLiteralMapKeys);
            Collections.sort(listBooleanPropertyMapKeys);
            Collections.sort(listIntegerPropertyMapKeys);
            Collections.sort(listDoublePropertyMapKeys);
            log.info("排序耗时{}ms", System.currentTimeMillis() - start1);
            Map<String, List<String>> key = new HashMap<>();
            key.put(CommonConstants.SIMULATION_INSTANCE, instanceMapKeys);
            key.put(CommonConstants.SIMULATION_BOOLEAN_PROPERTY, booleanPropertyMapKeys);
            key.put(CommonConstants.SIMULATION_INTEGER_PROPERTY, integerPropertyMapKeys);
            key.put(CommonConstants.SIMULATION_DOUBLE_PROPERTY, doublePropertyMapKeys);
            key.put(CommonConstants.SIMULATION_STRING_PROPERTY, stringPropertyMapKeys);
            key.put(CommonConstants.SIMULATION_INSTANCE_PROPERTY, instancePropertyMapKeys);
            key.put(CommonConstants.SIMULATION_LIST_STRING_PROPERTY, listStringPropertyMapKeys);
            key.put(CommonConstants.SIMULATION_LIST_INSTANCE_PROPERTY, listInstancePropertyMapKeys);
            key.put(CommonConstants.SIMULATION_INSTANCE_TYPE, instanceTypeMapKeys);
            key.put(CommonConstants.SIMULATION_ENUM_LITERAL, enumLiteralMapKeys);
            key.put(CommonConstants.SIMULATION_LIST_BOOLEAN_PROPERTY, listBooleanPropertyMapKeys);
            key.put(CommonConstants.SIMULATION_LIST_INTEGER_PROPERTY, listIntegerPropertyMapKeys);
            key.put(CommonConstants.SIMULATION_LIST_DOUBLE_PROPERTY, listDoublePropertyMapKeys);
            dataStore.put(uuid, mofDataStore);
            keyStore.put(uuid, key);
            try {
                data.put(CommonConstants.SIMULATION_UUID, uuid);
                dataCount = ObjectMapperFactory.getMapper().writer().writeValueAsString(data);
                // 延迟任务：在延迟300秒后执行数据删除任务，防止仿真服务挂了，这块数据一直保存在内存中
                Runnable delayedTask = () -> {
                    dataStore.remove(uuid);
                    keyStore.remove(uuid);
                };

                // 延迟执行任务
                executorService.schedule(delayedTask, 300, TimeUnit.SECONDS);
            } catch (JsonProcessingException e) {
                throw AbortExecutionException.build(ErrorCode.OBJECT_CONVERT_ERROR, e);
            }
        } else {
            dataStore.remove(oldUuid);
            keyStore.remove(oldUuid);
        }
        return dataCount;
    }

    @NotNull
    public String querySimulationJsonData(String projectId, List<String> instanceIds) {
        LogUtil.printOnlineLogs("projectId: {}, instanceIds: {}", projectId, instanceIds);
        long startTime = System.currentTimeMillis();
        final MofDataStore mofDataStore = querySimulationJsonDataInfo(projectId, instanceIds);
        String result;
        try {
            result = ObjectMapperFactory.getMapper().writer().writeValueAsString(mofDataStore);
        } catch (JsonProcessingException e) {
            throw AbortExecutionException.build(ErrorCode.OBJECT_CONVERT_ERROR, e);
        }
        log.info("all used time:" + (System.currentTimeMillis() - startTime));
        return result;
    }

    @Nullable
    public String querySimulationJsonDataByPage(List<String> instanceIds, String mapType, Integer pageNum, Integer pageSize, String uuid) {
        LogUtil.printOnlineLogs("instanceIds: {}, mapType: {}, pageNum: {}, pageSize: {}, uuid: {}",
                instanceIds, mapType, pageNum, pageSize, uuid);
        long startTime = System.currentTimeMillis();
        final Map<String, Object> needStore = new HashMap<>();
        Collections.sort(instanceIds);
        final MofDataStore store = dataStore.get(uuid);
        if (store.getInstanceMap().isEmpty()) {
            return null;
        }
        final Map<String, List<String>> ks = keyStore.get(uuid);
        int startIndex = (pageNum - 1) * pageSize;
        switch (mapType) {
            case CommonConstants.SIMULATION_INSTANCE: {
                final Map<String, SimulationInstanceRecord> map = store.getInstanceMap();
                // 将Map的键存储到List中
                final List<String> keys = ks.get(CommonConstants.SIMULATION_INSTANCE);
                // 计算当前页码对应的索引范围
                int endIndex = Math.min(startIndex + pageSize, keys.size());
                // 获取当前页码的数据列表
                final List<String> currentPageData = startIndex < endIndex ? keys.subList(startIndex, endIndex) : new ArrayList<>();
                // 输出当前页码的数据列表的键值对
                for (String key : currentPageData) {
                    needStore.put(key, map.get(key));
                }
                break;
            }
            case CommonConstants.SIMULATION_BOOLEAN_PROPERTY: {
                final Map<String, Map<String, Boolean>> map = store.getBooleanPropertyMap();
                final List<String> keys = ks.get(CommonConstants.SIMULATION_BOOLEAN_PROPERTY);
                fillStore(startIndex, pageSize, keys, needStore, map);
                break;
            }
            case CommonConstants.SIMULATION_INTEGER_PROPERTY: {
                final Map<String, Map<String, Integer>> map = store.getIntegerPropertyMap();
                final List<String> keys = ks.get(CommonConstants.SIMULATION_INTEGER_PROPERTY);
                fillStore(startIndex, pageSize, keys, needStore, map);
                break;
            }
            case CommonConstants.SIMULATION_DOUBLE_PROPERTY: {
                final Map<String, Map<String, Double>> map = store.getDoublePropertyMap();
                final List<String> keys = ks.get(CommonConstants.SIMULATION_DOUBLE_PROPERTY);
                fillStore(startIndex, pageSize, keys, needStore, map);
                break;
            }
            case CommonConstants.SIMULATION_STRING_PROPERTY: {
                final Map<String, Map<String, String>> map = store.getStringPropertyMap();
                final List<String> keys = ks.get(CommonConstants.SIMULATION_STRING_PROPERTY);
                fillStore(startIndex, pageSize, keys, needStore, map);
                break;
            }
            case CommonConstants.SIMULATION_INSTANCE_PROPERTY: {
                final Map<String, Map<String, String>> map = store.getInstancePropertyMap();
                final List<String> keys = ks.get(CommonConstants.SIMULATION_INSTANCE_PROPERTY);
                fillStore(startIndex, pageSize, keys, needStore, map);
                break;
            }
            case CommonConstants.SIMULATION_LIST_STRING_PROPERTY: {
                final Map<String, Map<String, List<String>>> map = store.getListStringPropertyMap();
                final List<String> keys = ks.get(CommonConstants.SIMULATION_LIST_STRING_PROPERTY);
                fillStore(startIndex, pageSize, keys, needStore, map);
                break;
            }
            case CommonConstants.SIMULATION_LIST_INSTANCE_PROPERTY: {
                final Map<String, Map<String, List<String>>> map = store.getListInstancePropertyMap();
                final List<String> keys = ks.get(CommonConstants.SIMULATION_LIST_INSTANCE_PROPERTY);
                fillStore(startIndex, pageSize, keys, needStore, map);
                break;
            }
            case CommonConstants.SIMULATION_ENUM_LITERAL: {
                final Map<String, Map<String, String>> map = store.getEnumLiteralMap();
                final List<String> keys = ks.get(CommonConstants.SIMULATION_ENUM_LITERAL);
                fillStore(startIndex, pageSize, keys, needStore, map);
                break;
            }
            case CommonConstants.SIMULATION_LIST_BOOLEAN_PROPERTY: {
                final Map<String, Map<String, List<Boolean>>> map = store.getListBooleanPropertyMap();
                final List<String> keys = ks.get(CommonConstants.SIMULATION_LIST_BOOLEAN_PROPERTY);
                fillStore(startIndex, pageSize, keys, needStore, map);
                break;
            }
            case CommonConstants.SIMULATION_INSTANCE_TYPE: {
                final Map<String, Set<String>> map = store.getInstanceTypeMap();
                final List<String> keys = ks.get(CommonConstants.SIMULATION_INSTANCE_TYPE);
                int endIndex = Math.min(startIndex + pageSize, keys.size());
                final List<String> currentPageData = startIndex < endIndex ? keys.subList(startIndex, endIndex) : new ArrayList<>();
                for (String key : currentPageData) {
                    needStore.put(key, map.get(key));
                }
                break;
            }
            case CommonConstants.SIMULATION_LIST_DOUBLE_PROPERTY: {
                final Map<String, Map<String, List<Double>>> map = store.getListDoublePropertyMap();
                final List<String> keys = ks.get(CommonConstants.SIMULATION_LIST_DOUBLE_PROPERTY);
                fillStore(startIndex, pageSize, keys, needStore, map);
                break;
            }
            case CommonConstants.SIMULATION_LIST_INTEGER_PROPERTY: {
                final Map<String, Map<String, List<Integer>>> map = store.getListIntegerPropertyMap();
                final List<String> keys = ks.get(CommonConstants.SIMULATION_LIST_INTEGER_PROPERTY);
                fillStore(startIndex, pageSize, keys, needStore, map);
                break;
            }
            default:
                log.warn("Unexpected value: " + mapType);
        }
        String res;
        try {
            res = ObjectMapperFactory.getMapper().writer().writeValueAsString(needStore);
        } catch (JsonProcessingException e) {
            throw AbortExecutionException.build(ErrorCode.OBJECT_CONVERT_ERROR, e);
        }
        log.info("all used time:" + (System.currentTimeMillis() - startTime));
        return res;
    }

    private static <T> void fillStore(int startIndex, int pageSize, List<String> keys, Map<String, Object> needStore,
                                      Map<String, Map<String, T>> map) {
        LogUtil.printOnlineLogs("startIndex: {}, pageSize: {}, keys: {}", startIndex, pageSize, keys);
        int endIndex = Math.min(startIndex + pageSize, keys.size());
        final List<String> currentPageData = startIndex < endIndex ? keys.subList(startIndex, endIndex) : new ArrayList<>();
        // 输出当前页码的数据列表的键值对
        for (String key : currentPageData) {
            needStore.put(key, map.get(key));
        }
    }

    @Nullable
    private MofDataStore querySimulationJsonDataInfo(final String projectId, List<String> instanceIds) {
        LogUtil.printOnlineLogs("projectId: {}, instanceId: {}", projectId, instanceIds);
        MofDataStore mofDataStore = new MofDataStore();
        List<MetaClassInstance> instances = internalUmlService.fetchInstanceByIds(instanceIds, projectId);
        if (CollectionUtils.isEmpty(instances)) {
            return null;
        }
        List<ModelPropertyInfo> models = modelPropertyInfoService.createModelPropertyInfoAndTypeList(projectId, instances,
                Stream.of(UMLDefinitionConstants.Element_owner).collect(Collectors.toList()));

        List<MetaClassInstance> firstOwnerList = models.stream().map(model -> {
            if (model.getGivenTypes().contains(UMLDefinitionConstants.UMLDiagram)) {
                MetaClassInstance firstOwner = model.queryInstanceValue(UMLDefinitionConstants.Element_owner);
                if (Objects.nonNull(firstOwner)) {
                    return firstOwner;
                }
            }
            return null;
        }).filter(Objects::nonNull).collect(Collectors.toList());
        Map<String, ModelPropertyInfo> firstOwnerPropertyInfoMap = modelPropertyInfoService.createModelPropertyInfoMap(projectId, firstOwnerList,
                Stream.of(UMLDefinitionConstants.Element_owner).collect(Collectors.toList()));

        List<MetaClassInstance> targetInstances = findTargetInstance(models, firstOwnerPropertyInfoMap);
        // 查找所有当前选中对象的子模块
        final List<String> targetIds = targetInstances.stream().map(MetaClassInstance::getId).collect(Collectors.toList());
        final List<String> childrenCascade = this.internalUmlService.getChildrenCascadeIds(projectId, targetIds);
        childrenCascade.addAll(targetIds);
        final Set<String> allCascade = new HashSet<>();
        final Map<String, SimulationAttributeInfo> attributeMap = getSimulationAttributeMapFromJson();
        // 查找所有子模块及其type，以及type的子模块及其子模块可能包含的type等数据
        List<MetaClassInstance> allInstance = new ArrayList<>();
        Set<String> visitedInstanceIds = new HashSet<>();
        BlockingQueue<List<MetaClassInstance>> blockingQueue = new LinkedBlockingQueue<>();
        //IO密集型任务，CPU 核心数 * 2
        int availableCount = Runtime.getRuntime().availableProcessors() * 2;
        ExecutorService executor = Executors.newFixedThreadPool(availableCount);
        AtomicInteger queryStatus = new AtomicInteger(0);
        List<Callable<Void>> tasks = new ArrayList<>();
        Callable<Void> producer = () -> {
            try {
                //这一步耗时在12s左右
                findAllCascade(allCascade, new HashSet<>(childrenCascade), projectId, attributeMap, blockingQueue);
            } finally {
                queryStatus.incrementAndGet();
            }
            return Void.TYPE.newInstance();
        };
        Callable<Void> consumer = () -> {
            while (queryStatus.get() == 0 || blockingQueue.peek() != null) {
                List<MetaClassInstance> metaClassInstances = blockingQueue.poll();
                if (CollectionUtils.isEmpty(metaClassInstances)) {
                    continue;
                }
                List<MetaClassInstance> metaClassInstanceLists = metaClassInstances.stream().filter(e -> !visitedInstanceIds.contains(e.getId())).
                        peek(e -> visitedInstanceIds.add(e.getId())).collect(Collectors.toList());

                allInstance.addAll(metaClassInstanceLists);

                List<List<MetaClassInstance>> partition = Lists.partition(metaClassInstanceLists, BATCH_SIZE);

                for (List<MetaClassInstance> metaClassInstanceList : partition) {
                    executor.submit(() -> {
                        DataProcessor dataProcessor = new DataProcessor(metaClassInstanceList, mofDataStore, projectId, internalUmlService, internalSpecificationService);
                        try {
                            dataProcessor.call();
                        } catch (AbortExecutionException ex) {
                            log.error("DataProcessor call method occur exception!", ex);
                        }
                    });
                }
            }
            return Void.TYPE.newInstance();
        };
        tasks.add(producer);
        tasks.add(consumer);
        try {
            executor.invokeAll(tasks);
            executor.shutdown();
            if (!executor.awaitTermination(300, TimeUnit.SECONDS)) {
                executor.shutdownNow();
            }
        } catch (InterruptedException e) {
            log.error("仿真数据获取错误", e);
            Thread.currentThread().interrupt();
            executor.shutdownNow();
        }
        log.info("处理ibd图和元素直接的关联关系");
        dealIbdElementRelation(mofDataStore, allInstance, projectId);
        log.info("查找枚举数据");
        queryEnumLiteral(mofDataStore, projectId);
        log.info("合并内置数据");
        mergeDefaultData(mofDataStore, projectId);
        return mofDataStore;
    }

    @NotNull
    private Map<String, SimulationAttributeInfo> getSimulationAttributeMapFromJson() {
        try (InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream(SIMULATION_ELEMENT_ATTRIBUTE)) {
            return ObjectMapperFactory.getMapper().readValue(stream,
                    new TypeReference<HashMap<String, SimulationAttributeInfo>>() {
                    });
        } catch (IOException e) {
            throw AbortExecutionException.build(ErrorCode.JSON_DATA_PARSE_ERROR, e);
        }
    }

    @NotNull
    private static List<MetaClassInstance> findTargetInstance(List<ModelPropertyInfo> models,
                                                              Map<String, ModelPropertyInfo> firstOwnerPropertyInfoMap) {
        LogUtil.printSerializeOnlineLogs("models: ", models);
        return models.stream().map(model -> {
            MetaClassInstance targetInstance = model.getInstance();
            if (model.getGivenTypes().contains(UMLDefinitionConstants.UMLDiagram)) {
                MetaClassInstance firstOwner = model.queryInstanceValue(UMLDefinitionConstants.Element_owner);
                if (Objects.nonNull(firstOwner)) {
                    ModelPropertyInfo firstPropertyInfo = firstOwnerPropertyInfoMap.get(firstOwner.getId());
                    MetaClassInstance secondOwner = firstPropertyInfo.queryInstanceValue(UMLDefinitionConstants.Element_owner);
                    if (Objects.nonNull(secondOwner) && secondOwner.getClassifier().getId().equals(UMLDefinitionConstants.Class)) {
                        targetInstance = secondOwner;
                    } else {
                        targetInstance = firstOwner;
                    }
                }
            }
            return targetInstance;
        }).collect(Collectors.toList());
    }

    private void mergeDefaultData(MofDataStore mofDataStore, String projectId) {
        LogUtil.printOnlineLogs("mergeDefaultData -> projectId: ", projectId);
        MofDataStore defaultData = DefaultInstanceCache.getMofDataStore();
        if (defaultData.getInstanceMap().isEmpty()) {
            simulationInitService.loadAllDefaultMetaClassInstances(projectId);
            defaultData = DefaultInstanceCache.getMofDataStore();
        }
        final List<String> instanceIds = defaultData.getInstanceMap().values().stream()
                .map(SimulationInstanceRecord::getInstanceId).collect(Collectors.toList());
        QueryPropertyForm form = new QueryPropertyForm();
        final List<MetaClassInstance> metaClassInstances = this.internalUmlService.fetchInstanceByIds(instanceIds, projectId);
        form.add(metaClassInstances, UMLDefinitionConstants.NamedElement_name);
        final MofResultContainer container = this.internalUmlService.queryProperty(projectId, form);
        Map<String, Map<String, String>> stringPropertyMap = mofDataStore.getStringPropertyMap();
        metaClassInstances.forEach(v -> {
            String name = container.queryStringProperty(v.getId(), UMLDefinitionConstants.NamedElement_name);
            if (StringUtils.isNotEmpty(name)) {
                if (stringPropertyMap.containsKey(v.getId())) {
                    stringPropertyMap.get(v.getId()).put(UMLDefinitionConstants.NamedElement_name, name);
                } else {
                    Map<String, String> newMap = new HashMap<>(1);
                    newMap.put(UMLDefinitionConstants.NamedElement_name, name);
                    stringPropertyMap.put(v.getId(), newMap);
                }
            }
        });
        mofDataStore.addMofDataStore(defaultData);
    }

    private void dealIbdElementRelation(MofDataStore mofDataStore, List<MetaClassInstance> allInstances, String projectId) {
        // 查询所有ibd图
        Map<String, Set<String>> givenTypes = internalUmlService.getGivenTypes(projectId, allInstances);

        List<MetaClassInstance> ibdInstances = allInstances.stream().filter(it ->
                givenTypes.get(it.getId()).contains(UMLDefinitionConstants.SysMLInternalBlockDiagram)).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(ibdInstances)) {
            ibdInstances.forEach(ibd -> {
                Map<String, String> instancePropertyMap = mofDataStore.getInstancePropertyMap().get(ibd.getId());
                if (!instancePropertyMap.isEmpty()) {
                    // 查询ibd图所处的block
                    String blockId = instancePropertyMap.get(UMLDefinitionConstants.Diagram_context);
                    if (StringUtils.isNotEmpty(blockId)) {
                        putMembersUseIbd(ibd, blockId, mofDataStore);
                    }
                }
            });
        }
    }

    private static void putMembersUseIbd(MetaClassInstance ibdInstance, String blockId, MofDataStore mofDataStore) {
        LogUtil.printSerializeOnlineLogs("ibdInstance: {}, blockId: {}", ibdInstance, blockId);
        // 存放所有members
        List<String> allMembers = new LinkedList<>();
        // 记录已经读取过的type模型，防止相互引用造成的无限循环
        Set<String> readElements = new HashSet<>();
        final Queue<String> q = new LinkedList<>();
        q.add(blockId);
        readElements.add(blockId);
        while (!q.isEmpty()) {
            String front = q.poll();
            final Map<String, List<String>> listInstancePropertyMap = mofDataStore.getListInstancePropertyMap().get(front);
            if (Objects.isNull(listInstancePropertyMap) || !listInstancePropertyMap.containsKey(UMLDefinitionConstants.Namespace_ownedMember)) {
                continue;
            }
            final List<String> members = listInstancePropertyMap.get(UMLDefinitionConstants.Namespace_ownedMember);
            if (CollectionUtils.isNotEmpty(members)) {
                putMemberInfo(allMembers, members, mofDataStore, readElements, q);
            }
        }
        final HashSet<String> allMembersSet = new HashSet<>(allMembers);
        for (String member : allMembersSet) {
            putUseRelation(member, ibdInstance, mofDataStore);
        }
    }

    private static void putMemberInfo(List<String> allMembers, List<String> members, MofDataStore mofDataStore,
                                      Set<String> readElements, Queue<String> queue) {
        LogUtil.printOnlineLogs("allMembers: {}, members: {}, readElements: {}, queue: {}", allMembers, members, readElements, queue);
        allMembers.addAll(members);
        for (String member : members) {
            final Map<String, String> instancePropertyMap = mofDataStore.getInstancePropertyMap().get(member);
            if (Objects.nonNull(instancePropertyMap) && instancePropertyMap.containsKey(UMLDefinitionConstants.TypedElement_type)) {
                String type = instancePropertyMap.get(UMLDefinitionConstants.TypedElement_type);
                if (!readElements.contains(type)) {
                    queue.add(type);
                    readElements.add(type);
                }
            }
        }
    }

    private static void putUseRelation(String member, MetaClassInstance ibdInstance, MofDataStore mofDataStore) {
        LogUtil.printSerializeOnlineLogs("member: {}, ibdInstance: {}", member, ibdInstance);
        if (mofDataStore.getListInstancePropertyMap().containsKey(member)) {
            Map<String, List<String>> memberListInstanceMap = mofDataStore.getListInstancePropertyMap().getOrDefault(member, new HashMap<>(1));
            if (memberListInstanceMap.containsKey(USED_IBD)) {
                List<String> usedIbdList = memberListInstanceMap.get(USED_IBD);
                if (!usedIbdList.contains(ibdInstance.getId())) {
                    ArrayList<String> list = new ArrayList<>(usedIbdList);
                    list.add(ibdInstance.getId());
                    memberListInstanceMap.put(USED_IBD, list);
                }
            } else {
                memberListInstanceMap.put(USED_IBD, Collections.singletonList(ibdInstance.getId()));
            }
        } else {
            HashMap<String, List<String>> stringListHashMap = new HashMap<>(1);
            stringListHashMap.put(USED_IBD, Collections.singletonList(ibdInstance.getId()));
            mofDataStore.getListInstancePropertyMap().put(member, stringListHashMap);
        }
    }

    private void queryEnumLiteral(MofDataStore mofDataStore, String projectId) {
        LogUtil.printOnlineLogs("queryEnumLiteral -> projectId: ", projectId);
        Map<String, SimulationInstanceRecord> instanceMap = mofDataStore.getInstanceMap();
        Map<String, Map<String, String>> enumLiteralMap = mofDataStore.getEnumLiteralMap();
        Map<String, Map<String, String>> stringPropertyMap = mofDataStore.getStringPropertyMap();
        Map<String, Set<String>> instanceTypeMap = mofDataStore.getInstanceTypeMap();
        ArrayList<String> propertyNames = new ArrayList<>(Arrays.asList(UMLDefinitionConstants.PseudostateKind,
                UMLDefinitionConstants.AggregationKind, UMLDefinitionConstants.ConnectorKind,
                UMLDefinitionConstants.CallConcurrencyKind, UMLDefinitionConstants.ExpansionKind,
                UMLDefinitionConstants.MessageKind, UMLDefinitionConstants.TransitionKind,
                UMLDefinitionConstants.InteractionOperatorKind, UMLDefinitionConstants.ObjectNodeOrderingKind,
                UMLDefinitionConstants.ParameterDirectionKind, UMLDefinitionConstants.ParameterEffectKind,
                UMLDefinitionConstants.VisibilityKind, UMLDefinitionConstants.SysML_VerdictKind,
                UMLDefinitionConstants.SysML_ControlValueKind, UMLDefinitionConstants.SysML_FeatureDirectionKind,
                UMLDefinitionConstants.SysML_FlowDirectionKind, UMLDefinitionConstants.SysML_QuantityKind,
                UMLDefinitionConstants.Message_messageKind, UMLDefinitionConstants.SysML_ValueType_quantityKind,
                UMLDefinitionConstants.Simulation_TimeUnitKind, UMLDefinitionConstants.MessageSort));
        final List<MetaClassInstance> enumerations = this.internalUmlService.querySpecifiedInstanceList(projectId,
                UMLDefinitionConstants.Enumeration);
        final QueryPropertyForm form = new QueryPropertyForm();
        form.put(enumerations, Collections.singletonList(UMLDefinitionConstants.Enumeration_ownedLiteral));
        final MofResultContainer container = this.internalUmlService.queryProperty(projectId, form);
        for (String propertyName : propertyNames) {
            List<MetaClassInstance> ownedLiteral = container.queryListInstanceProperty(propertyName, UMLDefinitionConstants.Enumeration_ownedLiteral);
            if (CollectionUtils.isNotEmpty(ownedLiteral)) {
                Map<String, Set<String>> allGivenTypes = this.internalUmlService.getGivenTypes(projectId, ownedLiteral);
                HashMap<String, String> stringStringHashMap = new HashMap<>();
                ownedLiteral.forEach(literal -> {
                    stringStringHashMap.put(literal.getId(), literal.getId());
                    instanceMap.put(literal.getId(), buildInstanceToRecord(literal));
                    HashMap<String, String> map = new HashMap<>();
                    final String name = literal.getDefinitionElement() instanceof MetaEnumerationLiteral ?
                            ((MetaEnumerationLiteral) literal.getDefinitionElement()).getName() : "";
                    map.put(UMLDefinitionConstants.NamedElement_name, name);
                    stringPropertyMap.put(literal.getId(), map);
                    instanceTypeMap.put(literal.getId(), allGivenTypes.get(literal.getId()));
                });
                enumLiteralMap.put(propertyName, stringStringHashMap);
            }
        }
    }


    private void findAllCascade(Set<String> allCascade, Set<String> allChildren, String projectId,
                                Map<String, SimulationAttributeInfo> attributeMap, BlockingQueue<List<MetaClassInstance>> blockingQueue) {
        LogUtil.printOnlineLogs("projectId: {}, allCascade: {}, allChildren: {}", projectId, allCascade, allChildren);
        allCascade.addAll(allChildren);
        QueryPropertyForm queryPropertyForm = new QueryPropertyForm();
        final List<MetaClassInstance> metaClassInstances = this.internalUmlService.fetchInstanceByIds(new ArrayList<>(allChildren), projectId);
        blockingQueue.offer(metaClassInstances);
        final Map<String, Set<String>> allGivenTypes = this.internalUmlService.getGivenTypes(projectId, metaClassInstances);
        for (MetaClassInstance metaClassInstance : metaClassInstances) {
            if (Objects.nonNull(metaClassInstance) && !BusinessJudgeService.isCreatedBySystem(metaClassInstance)) {
                List<String> allPropertyNames = new ArrayList<>();
                Set<String> givenTypes = allGivenTypes.get(metaClassInstance.getId());
                //添加所有待查propertyNames
                setPropertyNames(allPropertyNames, givenTypes, attributeMap);
                if (CollectionUtils.isNotEmpty(allPropertyNames)) {
                    queryPropertyForm.add(metaClassInstance, allPropertyNames);
                }
            }
        }
        final MofResultContainer container = queryPropertyForm.getPropertyMap().isEmpty() ?
                new MofResultContainer() :
                this.internalUmlService.queryProperty(projectId, queryPropertyForm);
        List<String> needRecursionIds = new ArrayList<>();
        Map<MetaClassInstance, List<String>> instanceMap = queryPropertyForm.getPropertyMap();
        if (!instanceMap.isEmpty()) {
            // 存放多重性propertyNames
            final Set<String> multiplicityProperties = new HashSet<>(
                    Arrays.asList(UMLDefinitionConstants.InstanceSpecification_classifier,
                            UMLDefinitionConstants.Association_memberEnd, UMLDefinitionConstants.BehavioralFeature_method,
                            UMLDefinitionConstants.SimulationConfig_executionTarget, UMLDefinitionConstants.Simulation_SelectPropertiesConfig_represents,
                            UMLDefinitionConstants.NamedElement_clientDependency, UMLDefinitionConstants.Dependency_supplier,
                            UMLDefinitionConstants.Element_appliedStereotype, UMLDefinitionConstants.Activity_partition));
            for (Map.Entry<MetaClassInstance, List<String>> instance : instanceMap.entrySet()) {
                // 将所有需要递归的id放入到needRecursionIds中
                findAllNeedRecursionIds(needRecursionIds, instance.getKey().getId(), container, allCascade, instance.getValue(), multiplicityProperties);
            }
        }
        if (CollectionUtils.isNotEmpty(needRecursionIds)) {
            List<String> childrenIds = this.internalUmlService.getChildrenCascadeIds(projectId, needRecursionIds);
            if (CollectionUtils.isNotEmpty(childrenIds)) {
                // 进入递归方法
                findAllCascade(allCascade, new HashSet<>(childrenIds), projectId, attributeMap, blockingQueue);
            }
        }
    }

    private static void findAllNeedRecursionIds(List<String> needRecursionIds, String metaClassInstanceId,
                                                MofResultContainer container, Set<String> allCascade, List<String> propertyNames,
                                                Set<String> listPropertyContain) {
        LogUtil.printOnlineLogs("needRecursionIds: {}, metaClassInstanceId: {}, container: {}, allCascade: {}, propertyNames: {}, listPropertyContain: {}",
                needRecursionIds, metaClassInstanceId, container, allCascade, propertyNames, listPropertyContain);
        propertyNames.forEach(propertyName -> {
            if (listPropertyContain.contains(propertyName)) {
                // 多重性数据
                List<String> multiplicityPropertyIds = findMultiplicityPropertyIds(metaClassInstanceId, propertyName, container, allCascade);
                needRecursionIds.addAll(multiplicityPropertyIds);
            } else {
                MetaClassInstance instanceProperty = container.queryInstanceProperty(metaClassInstanceId, propertyName);
                if (Objects.nonNull(instanceProperty) && !allCascade.contains(instanceProperty.getId())) {
                    needRecursionIds.add(instanceProperty.getId());
                }
            }
        });
    }

    @NotNull
    private static List<String> findMultiplicityPropertyIds(String metaClassInstanceId, String propertyName,
                                                            MofResultContainer container, Set<String> allCascade) {
        LogUtil.printOnlineLogs("metaClassInstanceId: {}, propertyName: {}, allCascade: {}", metaClassInstanceId, propertyName,
                allCascade);
        List<MetaClassInstance> listInstanceProperty = container.queryListInstanceProperty(metaClassInstanceId, propertyName);
        if (CollectionUtils.isNotEmpty(listInstanceProperty)) {
            return listInstanceProperty.stream().map(instanceProperty -> {
                if (!allCascade.contains(instanceProperty.getId())) {
                    return instanceProperty.getId();
                }
                return null;
            }).filter(Objects::nonNull).collect(Collectors.toList());
        }
        return Collections.emptyList();
    }


    private static void setPropertyNames(List<String> allPropertyNames, Set<String> givenTypes,
                                         Map<String, SimulationAttributeInfo> attributeMap) {
        LogUtil.printOnlineLogs("allPropertyNames: {}, givenTypes: {}", allPropertyNames, givenTypes);
        allPropertyNames.add(UMLDefinitionConstants.Element_appliedStereotype);
        givenTypes.forEach(it -> {
            SimulationAttributeInfo simulationAttributeInfo = attributeMap.get(it);
            if (Objects.nonNull(simulationAttributeInfo)) {
                List<String> attributes = simulationAttributeInfo.getAttributeKeys();
                allPropertyNames.addAll(attributes);
            }
        });
    }

    public boolean checkModelChange() {
        return InstanceVoUtils.checkModelChange();
    }

    @NotNull
    public ModelResultVo updateInstanceSpecificationValue(CreateInstanceSpecificationDTO createInstanceSpecificationDto) {
        LogUtil.printSerializeOnlineLogs("createInstanceSpecificationDto: ", createInstanceSpecificationDto);
        final String projectId = createInstanceSpecificationDto.getProjectId();
        final List<InstacneSpecificationInfo> instanceSpecifications = createInstanceSpecificationDto.getInstanceSpecifications();

        ModelResultVo modelResultVo = new ModelResultVo();
        if (CollectionUtils.isEmpty(instanceSpecifications)) {
            log.warn("instanceSpecifications为空");
            return modelResultVo;
        }

        LocalTransaction transaction = transactionService.createTransaction(projectId, UPDATE_MODEL);
        try {

            InstanceTableSimulation instanceTableSimulation = new InstanceTableSimulation(projectId,
                    createInstanceSpecificationDto, internalUmlService);
            instanceTableSimulation.run();
            for (AddModelDTO addModelDTO : instanceTableSimulation.getBatchCommand().getAddModelDTOList()) {
                umlService.addModel(addModelDTO);
            }

            umlService.updateModelByBatch(instanceTableSimulation.getBatchCommand().getUpdateModelDTOList());
            // 修改slot的值
            internalSpecificationService.createValueSpecificationToSlotByBatch(projectId, instanceTableSimulation.getUpdateSlotValueDtoList());
            transactionService.commit(projectId);
            InstanceVoUtils.fillModelResultVo(modelResultVo, transaction);
        } catch (TransactionNotExistingException | LocalTransactionNotStartException e) {
            throw AbortExecutionException.build(ErrorCode.TRANSACTION_ERROR, e);
        } catch (Exception e) {
            transactionService.rollBack(projectId, transaction);
            throw AbortExecutionException.build(ErrorCode.ADD_MODEL_ERROR, e);
        }

        return modelResultVo;
    }

    @NotNull
    private static SlotInfo getSlotInfo(SlotInfo slotInfo) {
        LogUtil.printSerializeOnlineLogs("slotInfo: ", slotInfo);
        SlotInfo newSlotInfo = new SlotInfo();
        newSlotInfo.setFeatureId(slotInfo.getFeatureId());
        List<SlotValueInfo> values = slotInfo.getValues();
        List<SlotValueInfo> valueList = new ArrayList<>();
        for (SlotValueInfo slotValueInfo : values) {
            SlotValueInfo newSlotValueInfo = new SlotValueInfo();
            newSlotValueInfo.setType(slotValueInfo.getType());
            Object value = slotValueInfo.getValue();
            if (Objects.isNull(value)) {
                continue;
            }
            newSlotValueInfo.setValue(value);
            if (value instanceof Map) {
                Map<String, Object> valueMap = new HashMap<>((Map<? extends String, ?>) value);
                newSlotValueInfo.setValue(valueMap.get(ID));
            }
            valueList.add(newSlotValueInfo);
        }
        newSlotInfo.setValues(valueList);
        return newSlotInfo;
    }

    @NotNull
    private UpdateSlotValueDto getUpdateSlotValueDto(String projectId, String instanceSpecificationId, Map<String, String> slotFeatureMap, SlotInfo slotInfo) {
        LogUtil.printOnlineLogs("projectId: {}, instanceSpecificationId: {}", projectId, instanceSpecificationId);
        String propertyId = slotInfo.getFeatureId();
        final MetaClassInstance property = internalUmlService.fetchInstance(propertyId, projectId);
        final MetaClassInstance typeInstance = internalUmlService.queryInstanceProperty(projectId, property,
                UMLDefinitionConstants.TypedElement_type);
        String slotId = slotFeatureMap.get(propertyId);
        UpdateSlotValueDto updateSlotValueDto = new UpdateSlotValueDto();

        // 创建slot
        if (StringUtils.isEmpty(slotId)) {
            CommandParameter slotParameter = CommandParameter.builder()
                    .projectId(projectId)
                    .typeId(UMLDefinitionConstants.Slot)
                    .type(CommandAddType.MODEL)
                    .parentId(instanceSpecificationId)
                    .instanceId(ModelConstantURI.initInstanceId())
                    .build();
            MetaClassInstance slot = umlService.addModel(slotParameter);
            umlService.updateModel(projectId, slot.getId(), UMLDefinitionConstants.Slot_definingFeature,
                    property);
            slotId = slot.getId();
        }

        updateSlotValueDto.setSlotId(slotId);
        List<SlotValueInfo> values = slotInfo.getValues();
        List<UpdateModelDTO> updateModelDTOS = new ArrayList<>();
        List<SlotValueInfo> slotValueInfos = values.stream().map(value -> {
            String type = value.getType();
            SlotValueInfo slotValueInfo = new SlotValueInfo();
            slotValueInfo.setType(type);
            if (StringUtils.equals(type, UMLDefinitionConstants.InstanceValue) && Objects.nonNull(typeInstance)) {
                if (Objects.isNull(value.getValue()) || Objects.isNull(internalUmlService.fetchInstance(value.getValue().toString(), projectId))) {
                    MetaClassInstance instanceSpecification = internalUmlService.fetchInstance(instanceSpecificationId, projectId);
                    MetaClassInstance instanceSpecificationOwner = internalUmlService.queryInstanceProperty(projectId, instanceSpecification,
                            UMLDefinitionConstants.Element_owner);
                    CommandParameter instanceParameter = CommandParameter.builder()
                            .projectId(projectId)
                            .typeId(UMLDefinitionConstants.InstanceSpecification)
                            .type(CommandAddType.MODEL)
                            .parentId(Objects.requireNonNull(instanceSpecificationOwner).getId())
                            .instanceId(ModelConstantURI.initInstanceId())
                            .build();
                    MetaClassInstance slotInstanceSpecification = umlService.addModel(instanceParameter);
                    log.info("创建一个InstanceSpecification作为slot的值");
                    updateModelDTOS.add(UpdateModelFactory.newInstance(projectId, slotInstanceSpecification.getId(),
                            UMLDefinitionConstants.InstanceSpecification_classifier, Collections.singletonList(typeInstance)));
                    slotValueInfo.setValue(slotInstanceSpecification.getId());
                } else {
                    slotValueInfo.setValue(value.getValue());
                }
            } else {
                slotValueInfo.setValue(value.getValue());
            }
            return slotValueInfo;
        }).collect(Collectors.toList());
        umlService.updateModelByBatch(updateModelDTOS);
        updateSlotValueDto.setValues(slotValueInfos);
        return updateSlotValueDto;
    }
}
